'use strict';

//自动结算订单，算出代理商和机构的佣金

var vk; // 全局vk实例
// 涉及的表名
const dbName = {
	//test: "vk-test", // 测试表
};

const maxRetries = 5;
var db = uniCloud.database(); // 全局数据库引用
var _ = db.command; // 数据库操作符
var $ = _.aggregate; // 聚合查询操作符
/**
 * 权限注意：访问以下链接查看
 * 文档地址：https://vkdoc.fsq.pub/client/uniCloud/cloudfunctions/cloudObject.html#内置权限
 */
var cloudObject = {
	isCloudObject: true, // 标记为云对象模式
	/**
	 * 请求前处理，主要用于调用方法之前进行预处理，一般用于拦截器、统一的身份验证、参数校验、定义全局对象等。
	 * 文档地址：https://vkdoc.fsq.pub/client/uniCloud/cloudfunctions/cloudObject.html#before-预处理
	 */
	_before: async function() {
		vk = this.vk; // 将vk定义为全局对象
		// let { customUtil, uniID, config, pubFun } = this.getUtil(); // 获取工具包
	},
	/**
	 * 请求后处理，主要用于处理本次调用方法的返回结果或者抛出的错误
	 * 文档地址：https://vkdoc.fsq.pub/client/uniCloud/cloudfunctions/cloudObject.html#after-后处理
	 */
	_after: async function(options) {
		let {
			err,
			res
		} = options;
		if (err) {
			return; // 如果方法抛出错误，直接return;不处理
		}
		return res;
	},
	/**
	 * 获取列表
	 * @url client/shujutj/ph/auto_agent.getList 前端调用的url参数地址
	 */
	getList: async function(data) {
		let res = {
			code: 0,
			msg: ''
		};
		let {
			item
		} = data;
		let {
			todayStart,
			todayEnd
		} = vk.pubfn.getCommonTime(new Date()); //获取时间范围
		let sevenDayStartAgo = vk.pubfn.getOffsetTime(todayStart, {
			day: 7,
			mode: "before", // after 之后 before 之前
		});
		// 业务逻辑开始-----------------------------------------------------------
		//查询需要更换状态的订单
		let res_recharge_id = await vk.baseDao.select({
			dbName: "a_recharge", // 表名
			getCount: false, // 是否需要同时查询满足条件的记录总数量，默认false
			getMain: false, // 是否只返回rows数据，默认false
			pageIndex: 1, // 当前第几页
			pageSize: 300, // 每页条数
			whereJson: { // 条件
				invite_code: item._id,
				pay_status: 1,
				_add_time: _.lt(sevenDayStartAgo),
				commission_is: false
			},
			// 代表只显示_id和money字段
			fieldJson: {
				_id: true,
				shifu_amount: true
			},
		});
		console.log("79行=》", res_recharge_id.rows.length);
		// b=b*1-1;
		// b = res_recharge_id.rows.length;
		if (res_recharge_id.rows.length == 0) {
			res.msg = '结算完成'
			return res;
		}
		//获取机构的佣金比例
		const commission_rate_middleman = await vk.baseDao.findById({
			dbName: "uni-id-users",
			id: item.middleman_id,
			fieldJson: {
				commission_rate: true
			},
		});

		if (commission_rate_middleman.commission_rate === null || commission_rate_middleman.commission_rate ===
			undefined) {
			res.msg = '机构佣金比例不存在';
			return res;
		}
		const commission_rate = commission_rate_middleman.commission_rate;
		let new_RequestId = vk.pubfn.getUniCloudRequestId(); //获取本次请求ID
	
		for (var i = 0; i < res_recharge_id.rows.length; i++) {
			// Start transaction
			// db.timeout = 70000;
			// const transaction = await vk.baseDao.startTransaction({
			// 	timeout: 70000
			// });
			let money_sum = 0; //求和金额
			try {
				var ids = res_recharge_id.rows[i]._id;
				let updateRes = 0;
				// 更新佣金结算状态
				try {
					updateRes = await vk.baseDao.updateById({
						// db: transaction,
						dbName: "a_recharge",
						id: ids,
						dataJson: { // 需要修改的数据
							commission_is: true
						},
					});
				} catch (err) {
					console.error(`122updateRes`, err)
				}
				if (updateRes > 0) {
					money_sum = money_sum + res_recharge_id.rows[i].shifu_amount;
				}
				//换算后的佣金(分)
				// let commission_agent = vk.pubfn.toDecimal(money_sum * 0.8, 2);
				// let commission_middleman = vk.pubfn.toDecimal(money_sum * 0.1, 2);
				//换算后的佣金(分)
				let commission_agent = vk.pubfn.toDecimal(money_sum * item.commission_rate, 2);
				let commission_middleman = vk.pubfn.toDecimal(money_sum * (commission_rate - item
					.commission_rate), 2);
				console.log("commission_middleman=", commission_middleman);
				let num_agent=0
				try {
					// 更新代理商的佣金金额
					 num_agent = await vk.baseDao.updateById({
						// db: transaction,
						dbName: 'uni-id-users',
						id: item._id,
						dataJson: {
							account_balance: _.inc(commission_agent * 1)
						},
					});
				} catch (err) {
					console.error(`num_agent153`, err)
				}
				
				
				let num_middleman=0
				try {
					// 更新机构的佣金金额
					 num_middleman = await vk.baseDao.updateById({
						// db: transaction,
						dbName: 'uni-id-users',
						id: item.middleman_id,
						dataJson: {
							account_balance: _.inc(commission_middleman * 1)
						},
					});
				} catch (err) {
					console.error(`169num_middleman`, err)
				}
				
				//插入佣金结算记录
				let insertRes = await vk.baseDao.add({
					// db: transaction,
					dbName: "a_commission_log", // 表名
					dataJson: { // 需要新增的数据 json格式
						middleman_id: item.middleman_id,
						agent_id: item._id,
						commission_middleman: commission_middleman,
						commission_agent: commission_agent,
						order_id: res_recharge_id.rows[i]._id,
						num_middleman:num_middleman,//机构是否更改过账户金额（0有可能是没有更新，有可能是算出的值为0）
						num_agent:num_agent,//代理商是否更改过账户金额
						updateRes:updateRes,//订单表的计算状态是否更改过
						RequestId: new_RequestId
					}
				});
				// if (insertRes  && num_agent > 0) {
				// 	// 提交事务
				// 	try {
				// 		await transaction.commit();
				// 	} catch (err) {
				// 		console.log("174", err);
				// 	}
				// 	//佣金结算成功
				// 	res.cwxx = "佣金结算成功";
				// 	console.log(`transaction succeeded`);

				// } else {
				// 	res.code = -1;
				// 	res.cwxx = "佣金结算失败";
				// 	// 事务回滚
				// 	await transaction.rollback();
				// }

			} catch (err) {
				// 事务回滚
				// await transaction.rollback();
				// console.error(`transaction error`, err)
				return res;
			}
		}
		try {
			// await this.getList(data)
			vk.callFunction({
				name: "hedian",
				url: 'admin/auto_run/pub/auto_settle_money.getList',
				title: '请求中...',
				data: {
					item
				}
			});
			
		} catch (err) {
			return res;
		}

		// 业务逻辑结束-----------------------------------------------------------
		// 等待500毫秒，给一个请求发出去的时间
		return await new Promise((resolve, reject) => {
		  setTimeout(() => {
		    resolve(res)
		  }, 500)
		})
		// return res;
	},
	test: async function(data) {
		// // 返回被修改的记录条数
		// let num = await vk.baseDao.update({
		// 	dbName: "a_recharge", // 表名
		// 	whereJson: { // 条件
		// 		invite_code: '6423d1b528064a03b77cdb76',
		// 	},
		// 	dataJson: { // 需要修改的数据
		// 		commission_is: false
		// 	}
		// });
		let num = await vk.baseDao.count({
			dbName: "a_commission_log", // 表名
			whereJson: { // 条件
				_add_time: _.gte(1681660800000).lte(1681747200000)
			}
		});
		console.log("239=>", num);
		return num;
	},
	getList2: async function(data) {
		let res = {
			code: 0,
			msg: ''
		};
		let {
			item
		} = data;
		let {
			todayStart,
			todayEnd
		} = vk.pubfn.getCommonTime(new Date()); //获取时间范围
		let sevenDayStartAgo = vk.pubfn.getOffsetTime(todayStart, {
			day: 7,
			mode: "before", // after 之后 before 之前
		});

		// 业务逻辑开始-----------------------------------------------------------
		//查询需要更换状态的订单
		const rechargeWhere = {
			invite_code: item._id,
			pay_status: 1,
			_add_time: _.lt(sevenDayStartAgo),
			commission_is: false
		};

		const rechargeField = {
			_id: true,
			shifu_amount: true
		};

		const rechargeOrders = await vk.baseDao.select({
			dbName: "a_recharge",
			pageIndex: 1,
			pageSize: 200,
			whereJson: rechargeWhere,
			fieldJson: rechargeField,
		});

		console.log("79行=》", rechargeOrders.rows.length);

		if (rechargeOrders.rows.length === 0) {
			res.msg = '结算完成';
			return res;
		}

		//获取机构的佣金比例
		const commission_rate_middleman = await vk.baseDao.findById({
			dbName: "uni-id-users",
			id: item.middleman_id,
			fieldJson: {
				commission_rate: true
			},
		});

		if (commission_rate_middleman.commission_rate === null || commission_rate_middleman.commission_rate ===
			undefined) {
			res.msg = '机构佣金比例不存在';
			return res;
		}
		const commission_rate = commission_rate_middleman.commission_rate;
		let item1 = item;
		let batchRun_agents = await vk.pubfn.batchRun({
			// 批量执行函数
			main: async (item, commission_rate, item1, order, index) => {
				await vk.pubfn.sleep((Math.floor(Math.random() * (3 - 0)) + 0) * 100);
				await performWriteOperation(order, item1, commission_rate);
				return {
					code: 0,
					index
				}
			},
			concurrency: 300, // 最大并发量，如果设置为1，则会按顺序执行
			data: rechargeOrders.rows // 数据源，这些数据会依次跑一遍main函数，相当于for循环里的数组
		});
		// }


		try {
			await this.getList(data);
		} catch (err) {
			return res;
		}

		// 业务逻辑结束-----------------------------------------------------------
		return res;

		async function performWriteOperation(order, item1, commission_rate, retries = 0) {
			// 开启事务
			db.timeout = 60000;
			const transaction = await vk.baseDao.startTransaction({
				timeout: 60000
			});

			let money_sum = 0;

			try {
				const id = order._id;
				let updateRes = 0;

				// 更新佣金结算状态
				try {
					updateRes = await vk.baseDao.updateById({
						db: transaction,
						dbName: "a_recharge",
						id: id,
						dataJson: {
							commission_is: true
						},
					});
				} catch (err) {
					console.error(`transaction error122`, err);
				}

				if (updateRes > 0) {
					money_sum += order.shifu_amount;
				}

				const commission_agent = vk.pubfn.toDecimal(money_sum * item1
					.commission_rate, 2);
				const commission_middleman = vk.pubfn.toDecimal(money_sum * (
					commission_rate - item1.commission_rate), 2);


				// 更新代理商的佣金金额
				const num_agent = await vk.baseDao.updateById({
					db: transaction,
					dbName: 'uni-id-users',
					id: item1._id,
					dataJson: {
						account_balance: _.inc(commission_agent * 1)
					},
				});

				// 更新机构的佣金金额
				const num_middleman = await vk.baseDao.updateById({
					db: transaction,
					dbName: 'uni-id-users',
					id: item1.middleman_id,
					dataJson: {
						account_balance: _.inc(commission_middleman * 1)
					},
				});


				//插入佣金结算记录
				const insertRes = await vk.baseDao.add({
					db: transaction,
					dbName: "a_commission_log",
					dataJson: {
						middleman_id: item1.middleman_id,
						agent_id: item1._id,
						commission_middleman: commission_middleman,
						commission_agent: commission_agent,
						order_id: res_recharge_id.rows[i]._id,
						RequestId: new_RequestId
					}
				});

				if (insertRes && num_middleman > 0 && num_agent > 0) {
					//提交事务
					await transaction.commit();
					res.cwxx = "佣金结算成功";
					console.log(`transaction succeeded`);
				} else {
					res.code = -1;
					res.cwxx = "佣金结算失败";
					await transaction.rollback();
				}
			} catch (error) {
				if (error.code === 112 && retries < maxRetries) {
					// 如果错误代码是112（WriteConflict），则进行重试
					await performWriteOperation(order, item1, commission_rate, retries + 1);
				} else {
					// 如果达到最大重试次数或遇到其他错误，则抛出错误
					throw error;
				}
				await transaction.rollback();
				console.error(`transaction error`);
			}
		}

	}
};


module.exports = cloudObject;
